package com.zheng.api.server.interceptor;

import com.zheng.api.common.constant.ApiConstant;
import com.zheng.api.common.constant.ApiResult;
import com.zheng.api.common.constant.ApiResultConstant;
import com.zheng.common.util.JsonUtil;
import com.zheng.common.util.PropertiesFileUtil;
import com.zheng.common.util.RedisUtil;
import com.zheng.common.util.XXTEAUtil;
import com.zheng.umbrella.dao.model.UmbrellaHardwareMachine;
import com.zheng.umbrella.dao.model.UmbrellaHardwareMachineExample;
import com.zheng.umbrella.rpc.api.UmbrellaHardwareMachineService;
import com.zheng.wechat.mp.dao.model.WechatMpGzuser;
import com.zheng.wechat.mp.dao.model.WechatMpGzuserExample;
import com.zheng.wechat.mp.rpc.api.WechatMpGzuserService;
import com.zheng.wechat.mp.rpc.api.WechatMpSystemAccountService;
import org.apache.commons.beanutils.converters.IntegerConverter;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.CollectionUtils;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * 公共拦截器
 * Created by shuzheng on 2017/3/25.
 */
public class ApiServerWebInterceptor extends HandlerInterceptorAdapter {

    private static final Logger LOGGER = LoggerFactory.getLogger(ApiServerWebInterceptor.class);
    /**
     * 缓存模块前缀
     */
    @Value("${Redis.CacheModule}")
    private String cacheModule;
    @Autowired
    WechatMpGzuserService wechatMpGzuserService;
    @Autowired
    WechatMpSystemAccountService wechatMpSystemAccountService;
    @Autowired
    UmbrellaHardwareMachineService umbrellaHardwareMachineService;
    /**
     * 例外的uri
     */
    private List<String> exceptUrls;
    public List<String> getExceptUrls() {
        return exceptUrls;
    }
    public void setExceptUrls(List<String> exceptUrls) {
        this.exceptUrls = exceptUrls;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 过滤ajax
//        if (null != request.getHeader("X-Requested-With") && "XMLHttpRequest".equalsIgnoreCase(request.getHeader("X-Requested-With"))) {
//            return true;
//        }
        //获取请求uri
        String requestUri = request.getRequestURI();
        if(requestUri.startsWith(request.getContextPath())){
            requestUri = requestUri.substring(request.getContextPath().length(), requestUri.length());
        }
        //系统根目录
        if (StringUtils.equals("/",requestUri)) {
            return true;
        }
        //放行exceptUrls中配置的url/api/v1/pay/notify/wxPayNotifyRes.htm
        for (String url:exceptUrls){
            if(url.endsWith("/**")){
                String tmpUrl = url.substring(0, url.length() - 3);
                if (requestUri.startsWith(tmpUrl)) {
                    return true;
                }
            } else if (requestUri.startsWith(url)) {
                return true;
            }
        }
        //验证token
        String token = request.getHeader("token");
        String account = request.getHeader("account");
        String machineCode = request.getParameter("machineCode");
        if(StringUtils.isBlank(token)){
            ApiResult result = new ApiResult(ApiResultConstant.INVALID_TOKEN,"token不能为空,请重新登陆");
            JsonUtil.outJsonObj(response, result);
            return false;
        }else if(StringUtils.isBlank(account)){
            ApiResult result = new ApiResult(ApiResultConstant.INVALID_TOKEN,"account不能为空,请重新登陆");
            JsonUtil.outJsonObj(response, result);
            return false;
        }else{
            String decryptToken = XXTEAUtil.decrypt(token, account);

            String skeyPath = cacheModule + ":" + ApiConstant.WECHATAPP_LOGIN_USER_TOKEN+":"+ account;
            String cacheToken = RedisUtil.get(skeyPath);
            if(!decryptToken.equals(cacheToken)){
                ApiResult result = new ApiResult(ApiResultConstant.INVALID_TOKEN,"token校验失败,可能信息已被篡改，请重新登陆");
                JsonUtil.outJsonObj(response, result);
                return false;
            }
            //采用拦截器更新用户代理
            try {
                if (StringUtils.isNotBlank(machineCode) && !"null".equals(machineCode)) {//如果存在设备码，则使用设备码获取代理
                    UmbrellaHardwareMachineExample machineExample = new UmbrellaHardwareMachineExample();
                    machineExample.createCriteria().andCodeEqualTo(machineCode);
                    UmbrellaHardwareMachine machine = umbrellaHardwareMachineService.selectFirstByExample(machineExample);
                    //更新代理
                    if (machine != null && machine.getAgentId() != null) {
                        WechatMpGzuser updateUser = new WechatMpGzuser();
                        updateUser.setUserAgentId(machine.getAgentId());
                        //更新条件
                        WechatMpGzuserExample updateExample = new WechatMpGzuserExample();
                        WechatMpGzuserExample.Criteria updateCriteria = updateExample.createCriteria();
                        updateCriteria.andIdEqualTo(Integer.valueOf(account));
                        //更新保存
                        wechatMpGzuserService.updateByExampleSelective(updateUser, updateExample);
                    }
                }
            }catch (Exception e){
                LOGGER.error("更新代理失败",e);
            }
            // zheng-ui静态资源配置信息
            String appName = PropertiesFileUtil.getInstance().get("app.name");
            String uiPath = PropertiesFileUtil.getInstance().get("zheng.ui.path");
            request.setAttribute("appName", appName);
            request.setAttribute("uiPath", uiPath);
            return true;
        }
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        super.afterCompletion(request, response, handler, ex);
    }

    @Override
    public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        super.afterConcurrentHandlingStarted(request, response, handler);
    }

}
